package com.qys.livesMall.app.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.qys.livesMall.app.user.model.entity.AppUserRelation;
import com.qys.livesMall.app.user.mapper.AppUserRelationMapper;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.AppUserRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.exception.enums.ExceptionEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户关系 服务实现类
 * </p>
 *
 * @author
 * @since 2023-10-13
 */
@Service
public class AppUserRelationServiceImpl extends ServiceImpl<AppUserRelationMapper, AppUserRelation> implements AppUserRelationService {

    @Autowired
    private IH2AppUserService userService;

    public List<AppUserRelation> get(Long userId){
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getUserId,userId);
        return list(wq);
    }

    @Override
    public List<AppUserRelation> init(Long userId, Long parent) {

        if (userId == null) {
            throw new QysException(ExceptionEnum.PARAM_IS_ERROR);
        }
        synchronized (userId) {
            List<AppUserRelation> userRelations=get(userId);
            if(CollectionUtils.isNotEmpty(userRelations)){
                return userRelations;
            };
            List<AppUserRelation> parents = new ArrayList<>();
            if (parent != null) {
                parents = get(parent);
                if (CollectionUtils.isEmpty(parents)) {
                    //查询用户表
                    H2AppUser user = userService.getById(parent.toString());
                    if (user != null) {
                        parents = init(Long.valueOf(user.getId()), user.getSuperior());
                    }
                }
            }
            List<AppUserRelation> users = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(parents)) {
                for (AppUserRelation p : parents) {
                    if (p.getParentId()==null){continue;}
                    AppUserRelation u = new AppUserRelation();
                    u.setUserId(userId);
                    u.setParentId(p.getParentId());
                    u.setLevel(p.getLevel() + 1);
                    users.add(u);
                }
                AppUserRelation userRelation = new AppUserRelation();
                userRelation.setUserId(userId);
                userRelation.setParentId(parent);
                userRelation.setLevel(1);
                users.add(userRelation);
            } else {
                AppUserRelation userRelation = new AppUserRelation();
                userRelation.setUserId(userId);
                userRelation.setParentId(null);
                userRelation.setLevel(0);
                users.add(userRelation);
            }
            saveBatch(users);
            return users;
        }
    }


    public void remove(Long userId){
        //获取到user下所有的用户
        if (userId==null){
            return;
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        List<AppUserRelation> list=list(wq);
        Set<Long> userIds=new HashSet<>();
        userIds.add(userId);
        if (CollectionUtils.isNotEmpty(list)){
            userIds.addAll(list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList()));
        }
        LambdaUpdateWrapper<AppUserRelation> uw=new LambdaUpdateWrapper();
        uw.in(AppUserRelation::getUserId,userIds);
        remove(uw);
        List<H2AppUser> users=userService.listByIds(userIds);
        for(H2AppUser user:users){
            init(Long.valueOf(user.getId()),user.getSuperior());
        }

    }

    private List<H2AppUser> getUserIds( List<AppUserRelation> list){
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<H2AppUser> users = userService.listByIds(list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList()));
        return users.stream().filter(o->!o.getDeleted()).collect(Collectors.toList());
    }

    @Override
    public List<H2AppUser> getLowerLevels(Long userId) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        return getUserIds(list(wq));
    }

    @Override
    public List<Long> getUserLowerLevels(Long userId) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        return getUserIdsById(list(wq));
    }


    @Override
    public List<H2AppUser> getLowerLevels(Long userId,Integer level){
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        if(level!=null){
            wq.eq(AppUserRelation::getLevel,level);
        }else {
            return  new ArrayList<>();
        }
        return getUserIds(list(wq));
    }

    @Override
    public List<H2AppUser> getLowerLevels(Long userId, List<Integer> levels) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        if(CollectionUtils.isNotEmpty(levels)){
            wq.in(AppUserRelation::getLevel,levels);
        }else {
            return new ArrayList<>();
        }
        return getUserIds(list(wq));
    }


    @Override
    public List<Long> getUserLowerLevels(Long userId, List<Integer> levels) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        if(CollectionUtils.isNotEmpty(levels)){
            wq.in(AppUserRelation::getLevel,levels);
        }else {
            return new ArrayList<>();
        }
        return getUserIdsById(list(wq));
    }

    @Override
    public List<Long> getUserLowerLevels(Long userId, Integer level) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        if(level!=null){
            wq.eq(AppUserRelation::getLevel,level);
        }else {
            return  new ArrayList<>();
        }
        return getUserIdsById(list(wq));
    }

    private List<Long> getUserIdsById( List<AppUserRelation> list){
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<H2AppUser> users = userService.listByIds(list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList()));
        return users.stream().filter(o->!o.getDeleted()).map(a->Long.valueOf(a.getId())).collect(Collectors.toList());
    }

    @Override
    public List<H2AppUser> getGreaterLevels(Long userId, Integer level) {
        if (userId==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.eq(AppUserRelation::getParentId,userId);
        if(level!=null){
            wq.gt(AppUserRelation::getLevel,level);
        }else {
            return new ArrayList<>();
        }
        return getUserIds(list(wq));
    }
    @Override
    public List<Long> getLowerLevels(String userName,Integer level){
        if (StringUtils.isBlank(userName)){
            return null;
        }
        LambdaQueryWrapper<H2AppUser> wrapper = new LambdaQueryWrapper<H2AppUser>()
                .eq(H2AppUser::getUserName, userName)
                .last("limit 1");
        H2AppUser user=userService.getOne(wrapper);
        if (user==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.select(AppUserRelation::getUserId);
        wq.eq(AppUserRelation::getParentId,user.getId());
        if(level!=null){
            wq.eq(AppUserRelation::getLevel,level);
        }else {
            return  new ArrayList<>();
        }
        List<AppUserRelation> list=list(wq);
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        return list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList());
    }

    @Override
    public List<Long> getLowerLevels(String userName, List<Integer> levels){
        if (StringUtils.isBlank(userName)){
            return null;
        }
        LambdaQueryWrapper<H2AppUser> wrapper = new LambdaQueryWrapper<H2AppUser>()
                .eq(H2AppUser::getUserName, userName)
                .last("limit 1");
        H2AppUser user=userService.getOne(wrapper);
        if (user==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.select(AppUserRelation::getUserId);
        wq.eq(AppUserRelation::getParentId,user.getId());
        if(CollectionUtils.isNotEmpty(levels)){
            wq.in(AppUserRelation::getLevel,levels);
        }else {
            return new ArrayList<>();
        }
        List<AppUserRelation> list=list(wq);
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        return list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList());
    }
    @Override
    public List<Long> getGreaterLevels(String userName,Integer level){
        if (StringUtils.isBlank(userName)){
            return null;
        }
        LambdaQueryWrapper<H2AppUser> wrapper = new LambdaQueryWrapper<H2AppUser>()
                .eq(H2AppUser::getUserName, userName)
                .last("limit 1");
        H2AppUser user=userService.getOne(wrapper);
        if (user==null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<AppUserRelation> wq=new LambdaQueryWrapper();
        wq.select(AppUserRelation::getUserId);
        wq.eq(AppUserRelation::getParentId,user.getId());
        if(level!=null){
            wq.gt(AppUserRelation::getLevel,level);
        }else {
            return  new ArrayList<>();
        }
        List<AppUserRelation> list=list(wq);
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        return list.stream().map(AppUserRelation::getUserId).collect(Collectors.toList());
    }

    @Override
    public List<Long> getValidUser(List<Long> userIds) {
        return baseMapper.getValidUser(userIds);
    }

    @Override
    public List<Long> getValidShop(List<Long> userIds) {
        return baseMapper.getValidShop(userIds);
    }

    @Override
    public List<Long> getGradeValidUser(List<Long> userIds) {
        return baseMapper.getGradeValidUser(userIds);
    }

}
